/**
 * tigerrad
 * fall 2006
 */

#ifndef _TEXTURE_H
#define _TEXTURE_H

#include "Util.h"

/**
 * Abstraction of an OpenGL Texture.
 */
class Texture
{
	public:
		/**
		 * Constructor.  An OpenGL name will be automatically generated.
		 * @param name Debug name (id) 
		 * @param s Texture size (width, height)
		 * @param target Texture target (for example, GL_TEXTURE_2D)
		 * @param intFormat Texture internal format
		 */
		Texture(const std::string& name, const Vec2s& s, 
				GLenum target, GLenum intFormat)
			: _name(name), _size(s), 
			_target(target), _intFormat(intFormat), _glName(genGLName())
			{}
		
		/**
		 * Return the debug name.
		 */
		std::string getName() const { return _name; }

		/**
		 * Return the Texture size (width, height);
		 */
		Vec2s getSize() const { return _size; }

		/**
		 * Return the Texture target.
		 */
		GLenum getTarget() const { return _target; } 

		/**
		 * Return the Texture internal format.
		 */
		GLenum getInternalFormat() const { return _intFormat; }

		/**
		 * Return the OpenGL Texture name.
		 */
		GLuint getGLName() const { return _glName; }
		
		/**
		 * Draw the Texture to the screen.
		 */
		virtual void drawFullScreen() = 0;

		/**
		 * Read the Texture back from the GPU.
		 */
		virtual void readPixels() = 0;

		/**
		 * Return the Pixel at...at.
		 * @param at Pixel coord
		 */
		virtual Vec4 getPixel(Vec2s at) = 0;

		/**
		 * Bind the texture to the texture unit.
		 */
		void bind(GLenum unit=GL_TEXTURE0) {
			glActiveTexture(unit);
			glEnable(_target);
			glBindTexture(_target, _glName);
		}

		/**
		 * Destructor.
		 */
		virtual ~Texture() {}

	protected:

		/**
		 * Utility to generate the OpenGL name for the Texture.
		 */
		GLuint genGLName();
		
		std::string _name;
		Vec2s _size;
		GLenum _target;
		GLenum _intFormat;
		GLuint _glName;
		
};

typedef boost::shared_ptr<Texture> TexturePtr;
#endif

